//
// Created by Administrator on 2021/9/27.
//

#include "Geometry.h"

Geometry::Geometry() {
    ID = "Geometry" + std::to_string(rand());

    drawMode = DEFAULT_DRAW_MODE;
    position = new Vector3(0, 0, 0);
    rotation = new Vector3(0, 0, 0);
    scale = new Vector3(1, 1, 1);
}

Geometry::~Geometry() {
}

void Geometry::setDrawMode(DrawMode drawMode) {
    this -> drawMode = drawMode;
}

void Geometry::init() {
    setUpAttribute();
    shader = ShaderUtil::getShaderByName(shaderName);
    if(!vertex.empty()) shader.initAttribVBOArray(ShaderAttribType::VERTEX, vertex);
    if(!color.empty()) shader.initAttribVBOArray(ShaderAttribType::COLOR, color);

    log_info("init this:%s", this->getId().c_str());
    for(Geometry * child : children){
        child->init();
    }
}

Shader Geometry::getShader() {
    return shader;
}


void Geometry::draw() {
    shader.draw(drawMode);
    log_info("draw this:%d", this->getId().c_str());
    for(Geometry * child : children){
        child->draw();
    }
}


/**
 * 获得模型变换矩阵
 * @return 模型变换矩阵
 */
Matrix4x4 Geometry::getModelmatrix() {
    Matrix4x4 transform;
    //scale
    transform = Matrix4x4::scale(transform, *scale);
    //rotator
    Matrix4x4 rm = getRotationMatrix();
    transform = transform * rm;
    //translate
    transform = Matrix4x4::translation(transform, *position);

    return transform;
}

/**
 * 计算旋转矩阵
 * @return todo 因为这里后期要加 四元素旋转，所以单独抽个方法
 */
Matrix4x4 Geometry::getRotationMatrix() {
    Matrix4x4 rm;
    rm = Matrix4x4::rotation(rm, Angle::deg2rad(rotation->x), Vector3(1, 0, 0));
    rm = Matrix4x4::rotation(rm, Angle::deg2rad(rotation->y), Vector3(0, 1, 0));
    rm = Matrix4x4::rotation(rm, Angle::deg2rad(rotation->z), Vector3(0, 0, 1));
    return rm;
}

/**
* 平移
*/
void Geometry::setTranslate(const Vector3& v) {
    position->x = v.x;
    position->y = v.y;
    position->z = v.z;
}

/**
 * 旋转
 */
void Geometry::setRotator(const Vector3& v) {
    rotation->x = v.x;
    rotation->y = v.y;
    rotation->z = v.z;
}

/**
 * 缩放
 */
void Geometry::setScale(const Vector3& v) {
    scale->x = v.x;
    scale->y = v.y;
    scale->z = v.z;
}

String Geometry::getId() const {
    return ID;
}












